Amplify Gen2 で「The event source arn (AAA) and function (BBB) provided mapping already exists. Please update or delete the existing mapping with UUID 18cd3748-9a76-4a05-8c69-ba0b8c1a9d17」が発生した際の対処法

Amplify Gen2 で「The event source arn (AAA) and function (BBB) provided mapping already exists. Please update or delete the existing mapping with UUID 18cd3748-9a76-4a05-8c69-ba0b8c1a9d17」が発生した際の対処法

Clock Icon2025.01.07

いわさです。

Amplify Gen2 では Data コンポーネントとして AppSync + DynamoDB が使われています。
この DynamoDB に変更が発生した際に何か処理を行いたい場合があります。
実現するひとつの方法として DynamoDB Streams を使う方法があり、Amplify では DynamoDB Streams 自体はデフォルトで ON になっており、イベントソースマッピングさえ用意してやれば割と簡単に実装することが出来ます。次の公式ドキュメントでも紹介されています。

https://docs.amplify.aws/react/build-a-backend/functions/examples/dynamo-db-stream/

先日、上記方法で DynamoDB Stream を設定して色々と調整していたところ、クラウドリソースデプロイ時に次のようなエラーが発生しました。

The event source arn (AAA) and function (BBB) provided mapping already exists. Please update or delete the existing mapping with UUID 18cd3748-9a76-4a05-8c69-ba0b8c1a9d17

見慣れないエラーですがイベントソースマッピングが既にあるぞと怒られています。
なんだこれは...。

どうやらイベントソースマッピングの startingPosition を変更すると生じる問題のようだ

少し関係のないコードも含まれていますが、概ね次のようなコードで EventSourceMapping を追加していました。
そしてそれは問題なく動作していました。

amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { updateTotalScoreOnActivityFunction } from './functions/update-totalscore-on-activity/resource';
import { Effect, Policy, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Stack } from 'aws-cdk-lib';
import { EventSourceMapping, StartingPosition } from 'aws-cdk-lib/aws-lambda';

const backend = defineBackend({
  auth,
  data,
  updateTotalScoreOnActivityFunction,
});

const funcitonUpdateTotalScoreOnActivity = backend.updateTotalScoreOnActivityFunction.resources.lambda;
const policy = new Policy(
  Stack.of(funcitonUpdateTotalScoreOnActivity),
  "TotalScoreFunctionStreamingPolicy",
  {
    statements: [
      new PolicyStatement({
        effect: Effect.ALLOW,
        actions: [
          "dynamodb:DescribeStream",
          "dynamodb:GetRecords",
          "dynamodb:GetShardIterator",
          "dynamodb:ListStreams",
        ],
        resources: ["*"],
      }),
    ],
  }
);
backend.updateTotalScoreOnActivityFunction.resources.lambda.role?.attachInlinePolicy(policy);
const mapping = new EventSourceMapping(
  Stack.of(funcitonUpdateTotalScoreOnActivity),
  "TotalScoreFunctionEventSourceMapping",
  {
    eventSourceArn: backend.data.resources.tables["ScoreActivities"].tableStreamArn,
    target: funcitonUpdateTotalScoreOnActivity,
    batchSize: 100,
    startingPosition: StartingPosition.TRIM_HORIZON,
  }
);
mapping.node.addDependency(policy);

DynamoDB Streams の EventSourceMapping には読み取り開始位置の概念があります。
このい記事では各設定値について解説しませんが、今回の問題はデプロイ済みのコードに対して StartingPosition を変更した際に発生しました。
上記コードを次のように変更しましょう。

amplify/backend.ts
:

backend.updateTotalScoreOnActivityFunction.resources.lambda.role?.attachInlinePolicy(policy);
const mapping = new EventSourceMapping(
  Stack.of(funcitonUpdateTotalScoreOnActivity),
  "TotalScoreFunctionEventSourceMapping",
  {
    eventSourceArn: backend.data.resources.tables["ScoreActivities"].tableStreamArn,
    target: funcitonUpdateTotalScoreOnActivity,
    batchSize: 100,
    startingPosition: StartingPosition.LATEST,
  }
);
mapping.node.addDependency(policy);

デプロイしてみると次のエラーが発生しました。
Amplify Gen2 が CloudFormation スタックを更新しようとした際に発生していますね。

Failed resources:
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc-function1351588B-8VL1Z479FJEM | 12:21:45 PM | UPDATE_FAILED        | AWS::Lambda::EventSourceMapping | function/TotalScoreFunctionEventSourceMapping (TotalScoreFunctionEventSourceMapping847649A9) Resource handler returned message: "The event source arn (" arn:aws:dynamodb:ap-northeast-1:123456789012:table/ScoreActivities-4yru3jeflnfunjs5kulpajw3ti-NONE/stream/2024-11-13T03:02:00.117 ") and function (" amplify-hogehogegameda-updatetotalscoreonactivi-34aUji1KOXbb ") provided mapping already exists. Please update or delete the existing mapping with UUID 4cfbfe66-34c4-4a89-be64-c26a7a868ea1 (Service: Lambda, Status Code: 409, Request ID: 5e45c570-a0f1-4223-9835-d65a3185c667)" (RequestToken: e3b1585a-ffdd-c68f-b81f-aafbb6ddea7a, HandlerErrorCode: AlreadyExists)
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc | 12:21:47 PM | UPDATE_FAILED        | AWS::CloudFormation::Stack | function.NestedStack/function.NestedStackResource (function1351588B) Embedded stack arn:aws:cloudformation:ap-northeast-1:123456789012:stack/amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc-function1351588B-8VL1Z479FJEM/8a606550-8f7a-11ef-9620-0a15b7d1e905 was not successfully updated. Currently in UPDATE_ROLLBACK_IN_PROGRESS with reason: The following resource(s) failed to update: [TotalScoreFunctionEventSourceMapping847649A9]. 

The CloudFormation deployment has failed.
Caused By: Deployment failed: Error: The stack named amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "The event source arn (" arn:aws:dynamodb:ap-northeast-1:123456789012:table/ScoreActivities-4yru3jeflnfunjs5kulpajw3ti-NONE/stream/2024-11-13T03:02:00.117 ") and function (" amplify-hogehogegameda-updatetotalscoreonactivi-34aUji1KOXbb ") provided mapping already exists. Please update or delete the existing mapping with UUID 4cfbfe66-34c4-4a89-be64-c26a7a868ea1 (Service: Lambda, Status Code: 409, Request ID: 5e45c570-a0f1-4223-9835-d65a3185c667)" (RequestToken: e3b1585a-ffdd-c68f-b81f-aafbb6ddea7a, HandlerErrorCode: AlreadyExists), Embedded stack arn:aws:cloudformation:ap-northeast-1:123456789012:stack/amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc-function1351588B-8VL1Z479FJEM/8a606550-8f7a-11ef-9620-0a15b7d1e905 was not successfully updated. Currently in UPDATE_ROLLBACK_IN_PROGRESS with reason: The following resource(s) failed to update: [TotalScoreFunctionEventSourceMapping847649A9]. 

Resolution: Find more information in the CloudFormation AWS Console for this stack.

ちなみに、batchSize の変更などは問題がなくて、私が確認した際には startingPosition を変更すると 100% 事象が再現しました。
で、色々と調べていくとどうやら数年前からの既知の問題であることがわかってきました。

次の Issuer は SAM で同じ問題が生じたもので、どうやら CDK 以外に SAM や、コメントを見ると Terraform でも発生することがあるようです。
また、DynamoDB Streams に関係なく、EventSourceMapping を使っていれば SQS や Kinesis などでも発生するとのこと。

https://github.com/aws/serverless-application-model/issues/1320

対処法:同一 UUID のマッピングを削除してから更新する

おそらく startingPosition のみ新規 UUID を払い出そうとしているようで、新規ではなく UUID を指定して更新するよう怒られています。
ただし、Amplify から UUID を指定して更新するのはちょっと面倒そうだったので今回は対象 UUID のマッピングを事前に CLI で削除することにしました。

Failed resources:
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc-function1351588B-1K1E0KE2XUA5L | 2:02:00 PM | UPDATE_FAILED        | AWS::Lambda::EventSourceMapping | function/TotalScoreFunctionEventSourceMapping (TotalScoreFunctionEventSourceMapping847649A9) Resource handler returned message: "The event source arn (" arn:aws:dynamodb:ap-northeast-1:123456789012:table/ScoreActivities-6bwkpz6o4jcztg7mgvncvsa5rq-NONE/stream/2024-12-25T04:59:29.319 ") and function (" amplify-hogehogegameda-updatetotalscoreonactivi-8ldt3qFNuPFN ") provided mapping already exists. Please update or delete the existing mapping with UUID c879c0aa-1b36-4a18-bf32-5116f7b3763f (Service: Lambda, Status Code: 409, Request ID: 51954b8e-f531-416b-8e51-fb97e6177b4b)" (RequestToken: 0aba9ba0-ac48-e4e2-da98-bfddbda70e45, HandlerErrorCode: AlreadyExists)
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc | 2:02:05 PM | UPDATE_FAILED        | AWS::CloudFormation::Stack | function.NestedStack/function.NestedStackResource (function1351588B) Embedded stack arn:aws:cloudformation:ap-northeast-1:123456789012:stack/amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc-function1351588B-1K1E0KE2XUA5L/22c94110-c27d-11ef-9e89-0ec561906ed5 was not successfully updated. Currently in UPDATE_ROLLBACK_IN_PROGRESS with reason: The following resource(s) failed to update: [TotalScoreFunctionEventSourceMapping847649A9]. 

The CloudFormation deployment has failed.
Caused By: Deployment failed: Error: The stack named amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "The event source arn (" arn:aws:dynamodb:ap-northeast-1:123456789012:table/ScoreActivities-6bwkpz6o4jcztg7mgvncvsa5rq-NONE/stream/2024-12-25T04:59:29.319 ") and function (" amplify-hogehogegameda-updatetotalscoreonactivi-8ldt3qFNuPFN ") provided mapping already exists. Please update or delete the existing mapping with UUID c879c0aa-1b36-4a18-bf32-5116f7b3763f (Service: Lambda, Status Code: 409, Request ID: 51954b8e-f531-416b-8e51-fb97e6177b4b)" (RequestToken: 0aba9ba0-ac48-e4e2-da98-bfddbda70e45, HandlerErrorCode: AlreadyExists), Embedded stack arn:aws:cloudformation:ap-northeast-1:123456789012:stack/amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc-function1351588B-1K1E0KE2XUA5L/22c94110-c27d-11ef-9e89-0ec561906ed5 was not successfully updated. Currently in UPDATE_ROLLBACK_IN_PROGRESS with reason: The following resource(s) failed to update: [TotalScoreFunctionEventSourceMapping847649A9]. 

Resolution: Find more information in the CloudFormation AWS Console for this stack.

% aws lambda delete-event-source-mapping --uuid c879c0aa-1b36-4a18-bf32-5116f7b3763f
{
    "UUID": "c879c0aa-1b36-4a18-bf32-5116f7b3763f",
    "StartingPosition": "TRIM_HORIZON",
    "BatchSize": 100,
    "MaximumBatchingWindowInSeconds": 0,
    "ParallelizationFactor": 1,
    "EventSourceArn": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/ScoreActivities-6bwkpz6o4jcztg7mgvncvsa5rq-NONE/stream/2024-12-25T04:59:29.319",
    "FunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:amplify-hogehogegameda-updatetotalscoreonactivi-8ldt3qFNuPFN",
    "LastModified": "2024-12-25T14:01:00+09:00",
    "LastProcessingResult": "No records processed",
    "State": "Deleting",
    "StateTransitionReason": "User action",
    "DestinationConfig": {
        "OnFailure": {}
    },
    "MaximumRecordAgeInSeconds": -1,
    "BisectBatchOnFunctionError": false,
    "MaximumRetryAttempts": -1,
    "TumblingWindowInSeconds": 0,
    "FunctionResponseTypes": [],
    "EventSourceMappingArn": "arn:aws:lambda:ap-northeast-1:123456789012:event-source-mapping:c879c0aa-1b36-4a18-bf32-5116f7b3763f"
}

:

 ✅  amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc

✨  Deployment time: 76.02s

Outputs:
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.allowUnauthenticatedIdentities = true
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.amplifyApiModelSchemaS3Uri = s3://amplify-hogehogegameda-amplifydataamplifycodege-25t9zxrau9o3/model-schema.graphql
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.authRegion = ap-northeast-1
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.awsAppsyncAdditionalAuthenticationTypes = API_KEY,AWS_IAM
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.awsAppsyncApiEndpoint = https://iahsmxg55zgthjfxez4nataxpi.appsync-api.ap-northeast-1.amazonaws.com/graphql
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.awsAppsyncApiId = 6bwkpz6o4jcztg7mgvncvsa5rq
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.awsAppsyncApiKey = da2-xxxxxxxx
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.awsAppsyncAuthenticationType = AMAZON_COGNITO_USER_POOLS
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.awsAppsyncRegion = ap-northeast-1
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.definedFunctions = ["amplify-hogehogegameda-updatetotalscoreonactivi-8ldt3qFNuPFN"]
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.deploymentType = sandbox
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.identityPoolId = ap-northeast-1:63c1f9f6-56fb-4dc4-8abc-e1a43db22c42
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.mfaConfiguration = OFF
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.mfaTypes = []
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.oauthClientId = 5lf2nie4vaunqkd6kof47u9mro
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.oauthCognitoDomain = 
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.oauthRedirectSignIn = https://example.com
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.oauthRedirectSignOut = 
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.oauthResponseType = code
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.oauthScope = ["profile","phone","email","openid","aws.cognito.signin.user.admin"]
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.passwordPolicyMinLength = 8
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.passwordPolicyRequirements = ["REQUIRES_NUMBERS","REQUIRES_LOWERCASE","REQUIRES_UPPERCASE","REQUIRES_SYMBOLS"]
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.region = ap-northeast-1
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.signupAttributes = ["email"]
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.socialProviders = 
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.userPoolId = ap-northeast-1_E0TRtWLbg
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.usernameAttributes = ["email"]
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.verificationMechanisms = ["email"]
amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc.webClientId = 5lf2nie4vaunqkd6kof47u9mro
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:123456789012:stack/amplify-hogehogefugaduga-iwasatakahito-sandbox-ba58f869cc/ad57a430-c27c-11ef-a6e2-0ae586d0dc2f

✨  Total time: 76.06s

[Sandbox] Watching for file changes...
File written: amplify_outputs.json

スタックが更新出来ました。
CLI を使わない場合は DynamoDB テーブルのマッピング設定から対象関数の関連付けを削除するでも OK です。

startingPosition の変更は普通は発生しないので、この対処で良いかなと個人的には思っています。
手動対応を回避したい理由がある場合はカスタムリソース的なものでUpdateEventSourceMappingを UUID 指定で呼び出すような作りにしてやる必要があると思います。

さいごに

本日は Amplify Gen2 で「The event source arn (AAA) and function (BBB) provided mapping already exists. Please update or delete the existing mapping with UUID 18cd3748-9a76-4a05-8c69-ba0b8c1a9d17」が発生した際の対処法を紹介しました。

Issue を見る限りでしばらく対処されていないようなので根本的な問題解決は難しそうな気配を感じます。
特定のケースで発生する問題なので、手動対応で凌げることを知っておきましょう。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.